<!--
~ Copyright 2018-present Open Networking Foundation
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~     http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<svg:defs xmlns:svg="http://www.w3.org/2000/svg">
    <svg:filter id="glow">
        <svg:feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0.9 0 0 0 0 0.9 0 0 0 0 1 0" />
        <svg:feGaussianBlur stdDeviation="2.5" result="coloredBlur" />
        <svg:feMerge>
            <svg:feMergeNode in="coloredBlur" />
            <svg:feMergeNode in="SourceGraphic"/>
        </svg:feMerge>
    </svg:filter>
</svg:defs>
<!-- Template explanation: Creates an SVG Line and in
    line 1) transform end A to the position calculated by the d3 force graph engine
    line 2) transform end B to the position calculated by the d3 force graph engine
    line 3) Give it various CSS styles depending on attributes
    ling 4) Change the line width depending on the scale
    line 4) When it is clicked, call the method that toggles the selection and
        emits an event.
    line 5) When the mouse is moved over call on enhance() function. This will
        flash up the port labels, and display the link in blue for 1 second
    Other child objects have their own description
-->
<svg:line xmlns:svg="http://www.w3.org/2000/svg"
        [attr.x1]="link.source?.x" [attr.y1]="link.source?.y"
        [attr.x2]="link.target?.x" [attr.y2]="link.target?.y"
        [ngClass]="['link', selected?'selected':'', enhanced?'enhanced':'', highlightAsString()]"
        [ngStyle]="{'stroke-width': (enhanced ? 4 : 2) * scale + 'px'}"
        (click)="toggleSelected(link, $event)"
        (mouseover)="enhance()">
<!--        [attr.filter]="highlighted?'url(#glow)':'none'">-->
    <svg:desc>{{link.id}} {{linkHighlight?.css}} {{isHighlighted}}</svg:desc>
</svg:line>
<svg:g xmlns:svg="http://www.w3.org/2000/svg"
       [ngClass]="['linkLabel']"
       [attr.transform]="'scale(' + scale + ')'">
    <!-- Template explanation: Creates SVG Text in the middle of the link to
          show traffic and in:
        line 1) Performs the animation 'linkLabelVisible' whenever the isHighlighted
            boolean value changes
        line 2 & 3) Sets the text at half way between the 2 end points of the line
        Note: we do not use an *ngIf to enable or disable this, because that would
        cause the fade out of the text to not work
    -->
    <svg:text xmlns:svg="http://www.w3.org/2000/svg"
              [@linkLabelVisible]="isHighlighted"
              [attr.x]="link.source?.x + (link.target?.x - link.source?.x)/2"
              [attr.y]="link.source?.y + (link.target?.y - link.source?.y)/2"
    >{{ linkHighlight?.label }}</svg:text>
</svg:g>
<!-- Template explanation: Creates an SVG Group if
    line 1) 'enhanced' is active and port text exists
    line 2) assigns classes to it
-->
<svg:g xmlns:svg="http://www.w3.org/2000/svg"
       *ngIf="enhanced && link.portA"
       class="portLabel"
       [attr.transform]="'translate(' + labelPosSrc.x + ',' + labelPosSrc.y + '),scale(' + scale + ')'">
    <!-- Template explanation: Creates an SVG Rectangle and in
        line 1) transform end A to the position calculated by the d3 force graph engine
        line 2) assigns classes to it
    -->
    <svg:rect
            [attr.x]="2 - textLength(link.portA)/2" y="-8"
            [attr.width]="4 + textLength(link.portA)" height="16" >
    </svg:rect>
    <!-- Template explanation: Creates SVG Text and in
        line 1) transform it to the position calculated by the method labelPosSrc()
        line 2) centre aligns it
        line 3) ensures that the text fills the rectangle by adjusting spacing
    -->
    <svg:text y="2" text-anchor="middle"
            [attr.textLength]= "textLength(link.portA)" lengthAdjust="spacing"
    >{{ link.portA }}</svg:text>
</svg:g>
<!-- A repeat of the above, but for the other end of the line -->
<svg:g xmlns:svg="http://www.w3.org/2000/svg"
       *ngIf="enhanced && link.portB"
       class="portLabel"
       [attr.transform]="'translate(' + labelPosTgt.x + ',' + labelPosTgt.y + '),scale(' + scale + ')'">
    <svg:rect
            [attr.x]="2 - textLength(link.portB)/2" y="-8"
            [attr.width]="4 + textLength(link.portB)" height="16">
    </svg:rect>
    <svg:text x="2" y="2" text-anchor="middle"
            [attr.textLength]= "textLength(link.portB)" lengthAdjust="spacing"
    >{{ link.portB }}</svg:text>
</svg:g>
